/**
 * Anderground project - Subway maps processor application.
 * Copyright (C) 2008-2009 Eldar Abusalimov, Ilya Shurigyn
 * 
 * This file is part of Anderground.
 * 
 * Anderground is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * Anderground is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Anderground.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.anderground.core.model;

import java.io.Serializable;

import org.anderground.core.util.Binder;
import org.anderground.core.util.BindingException;

/**
 * Tunnel class
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 */
public class Tunnel extends Transition implements Serializable {

	/**
	 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
	 */
	public final class Editor extends Transition.Editor {

		/**
		 * private constructor
		 */
		private Editor() {
		}

		/**
		 * @param smooth
		 *            the smooth
		 */
		public void setSmooth(boolean smooth) {
			Tunnel.this.smooth = smooth;
		}

		/**
		 * Safely changes the tunnel's line.
		 * 
		 * @param line
		 *            the new line
		 */
		public void setLine(Line line) {
			if (line == null) {
				throw new IllegalArgumentException(
						"the tunnel's line cannot be null");
			}
			if (Tunnel.this.line == line) {
				return;
			}
			if (isBound()) {
				try {
					Binder binder = getBinder();
					unbindFrom(binder);
					Tunnel.this.line = line;
					bindTo(binder);
				} catch (BindingException e) {
					assert false;
				}
			} else {
				Tunnel.this.line = line;
			}
		}

	}

	private static final long serialVersionUID = -4543497209763035413L;

	/** the Line to which Tunnel belongs */
	private Line line;

	/** indicates if we should draw this tunnel curved */
	private boolean smooth;

	transient private Editor editor;

	/**
	 * @param fromStation
	 * @param toStation
	 * @param time
	 *            - time is seconds between fromStation and toStation
	 * @param line
	 *            - Tunnel line
	 * @param smooth
	 *            - define tunnel smoothing
	 */
	public Tunnel(Station fromStation, Station toStation, int time, Line line,
			boolean smooth) {
		super(fromStation, toStation, time);
		if (line == null) {
			throw new IllegalArgumentException(
					"the tunnel's line cannot be null");
		}
		this.line = line;
		this.smooth = smooth;
	}

	/**
	 * @return the line
	 */
	public Line getLine() {
		return line;
	}

	/**
	 * @return the smooth
	 */
	public boolean isSmooth() {
		return smooth;
	}

	/**
	 * @return
	 */
	@Override
	Editor getEditor() {
		if (editor == null) {
			editor = new Editor();
		}

		return editor;
	}

	@Override
	public int hashCode() {
		if (isBound()) {
			return super.hashCode();
		} else {
			return super.hashCode() + line.hashCode() + (smooth ? 17 : 31);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}

		Tunnel another;
		if (obj instanceof Tunnel) {
			another = (Tunnel) obj;
		} else {
			return false;
		}

		if (!super.equals(obj)) {
			return false;
		}

		if (!line.equals(another.line)) {
			return false;
		}
		if (smooth != another.smooth) {
			return false;
		}

		return true;
	}

}
